The WordPress Search Widget is a classic HTML Form, but what if we want to show the results right away? In this tutorial, we will power up the WordPress Search Form with React and REST API to show the results immediately.
In a previous tutorial, I’ve shown how to use React for loading posts from various blogs through REST API. If you’re interested in such tutorial, you can check it out: How to use React to Render WordPress Content from the REST API. In that tutorial, I am also explaining how to install packages and prepare the package.json
.
See it in action on the video on Twitter:
Replacing the #WordPress Search widget with a #React Autocomplete Search with results from the REST API. Thank you @wesbos for ReactJS for Beginners and ES6! Thank you @zgordon for Gutenberg course and pushing me even more into advanced #JavaScript. pic.twitter.com/GJ6X11IDbs
— Igor Benić (@igorbenic) January 26, 2018
Setting up our Plugin
In terms of PHP, this will be a simple plugin. In terms of JavaScript, you’ll have to install several packages and create components so that our main JavaScript file can compile correctly. Since I’ve done that before, I will show you how to do it.
First, create a folder for your plugin. I will name it wp-search-react
and then create a file inside with the same name wp-search-react.php
. Inside that folder, create another one assets
and inside that create another one js
.
Inside the js
folder, create a JavaScript file public.js
and a folder components
. The folder components
will contain JavaScript files for each component in our code.
Installing Packages
To install packages that will compile our JavaScript, you need to have npm
and node
installed. If you don’t have that installed, go to https://nodejs.org and follow the instructions. Also, if you have older versions, update them.
Create a file package.json
in the main folder of our plugin and put this inside:
This will list all the packages that are needed to follow this tutorial. Now you need to open your terminal (command prompt) and open our plugin folder in it (probably by typing several cd
command to move into directories).
Once you’re in the main plugin folder wp-search-react
(in terminal), type npm install
. This might take some time to install all the packages.
Configuring Webpack
We will use Webpack to compile all the scripts together and also to transform ES6 or newer code into ES5 compatible code. If you’ve never configured Webpack, I would recommend reading/watching my tutorial: Configuring Webpack in WordPress for the First Time.
Create another file in our main plugin folder and name it webpack.config.js
and put this in:
Now you can run npm run watch
and Webpack should compile the public.js
into public.min.js
. On each change in that file, Webpack will recompile it.
Enqueueing our JavaScript
Before we go into JavaScript, we need to enqueue it on our site. Open our main plugin file and put all this information:
We are enqueuing our minified JavaScript file and we are also creating a global JavaScript object wp_react_js
that will hold the REST URL for searching posts. The %s
in the URL will be later replaced with the search term.
Activate the plugin from the Plugins page.
Replacing the WordPress Search
The first code that we will write will replace the inner parts of the search form with our new React parts. We need to find all the search forms on the page and render React parts in each.
We are importing React
and ReactDOM
so we can use React and manipulate the DOM through ReactDOM. Now, we are finding all the Search forms and we will render our React Elements inside.
Rendering the React Search Form
We will create a new React Component that will hold our new Search Form. First, let’s change our main JavaScript file.
We are importing our new SearchForm Component (that we will create below) so we can use it within public.js
. After importing it, we are putting that as a React Element using JSX in const searchFormElement
. We are using that constant when rendering it for each search form on the page.
Search Form Component
The code above will not work without the SearchForm
Component. Open the folder components
and create a file searchForm.js
.
Inside the render
method we are creating a simple <input />
. This input has an event registered onKeyUp
. Once that is triggered, we are calling the method getResults()
. To be able to use this
inside that method, we are binding it in the constructor
method.
Inside that constructor
method we are also building starting the initial setup through super(props)
and also preparing properties to be available through this.props
. Since searchForm
is our main Component (root), we will put the state there. In this state, we are setting 3 properties:
results
– an array of retrieved posts from our searchloading
– a boolean showing if the results are still loadingsearched
– a boolean showing if we have search terms in the input
Inside the method getResults(e)
, we are receiving the event object to retrieve the value. But before doing anything, we are checking if are still loading the previous results. If that is true, we are not proceeding with the new search.
Fetching the Results
Let’s populate our method getResults(e)
with the code that will fetch the results.
We are getting the search term inside the const search
. If we have more than 2 letters in it, we will start searching. Before we start fetching the results, we are setting the state properties loading
and searched
to TRUE
.
Then, we are getting the REST URL and replacing the %s
with our search term. After that, we are fetching the results, transforming the results into JSON and finally set the results in our state. We are also putting the property loading
to FALSE
.
If the search term has less than 3 letters, we are setting properties loading
and searched
to FALSE
.
Rendering the Results
We will not use this component to render the results directly. We will create another React Component for that.
At the beginning of the file, we are importing a new component searchResults
. We are also adding that element to the render
method and setting properties searched
, loading
and results
. This properties will be available inside the searchResults
component through this.props
.
Search Results Component
Inside the folder components
, add a new JavaScript file searchResults.js
.
At the beginning of this file, we are again importing a new component that we will create next. Inside the searchResults
component, we are preparing the properties through super(props)
. We don’t require anything else than a render
method to show the results.
The variable let results
will hold the text that will show under our field. If the results are still loading, we will show a text “Loading”. If there are any results, we will create a list of all retrieved posts. Each post will be rendered through the component searchResult
.
If we are not loading the results but there are no results for the inserted search term, the text will be “Nothing Found”.
Search Result Component
This is the last component that we have to create. This one will be used only to render one single result. Create a new file in the folder components
and name it searchResult.js
.
In the render
method we are returning a simple list element and we are rendering the content from the this.props.result
object which we have passed in the searchResults
component.
The Complete Plugin
I have prepared a complete plugin which you can use and then learn from reading the code. It is without any packages, so you would need to install them with npm install
. To make it even more complete, play around with CSS to style the results better than the default styles.
This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member
Conclusion
With React, we can enhance the user experience of our visitors on our WordPress site. With simple tweaks such as this one, we can slowly improve the performance of our site. By using the REST API, we are also getting a boost in performance when searching our site because we don’t have to load the whole WordPress site again.
Have you tried using REST API for searching posts or other content? Have you tried using React in WordPress? Share your experience in the comments below!
If you’ve played around with it and written CSS for much prettier output, share that also!
Become a Sponsor
Work fine, thank you for this example.
Currently for display below the searchfield the whole postobjects are returned from 10 first results. Would suggest to only get required fields and more possible results:
../posts?search=SEARCHTERM&_fields[]=link&_fields[]=title.rendered&per_page=100
If you search for e.g. “core” it shows all real results for “core” and also all Gutenberg posts because text “wp:core” is in all of them, weird.
Yes, currently, it is only displaying number of posts set in posts_per_page setting. Thank you for the example, other readers will certainly appreciate that!
As for the Gutenberg search issue, you might want to create a ticket for that in wp.org. That should not happen in my opinion.
Hey Igor, this is great and I’ve got it working like a charm. Maybe one suggestion: set a production build in package.json. I think I did this by doing the following (however, I really know nothing about webpack so this may not be the best method):
//…
“build:prod”: “webpack -p”,
//…
Hi Alex, thanks for the suggestion. You’re correct and that might be a good thing to do for production builds. But as far as I know, this command will set Webpack in a production environment and then compile everything for production. But if you don’t have a configuration for production, that won’t do much difference.
Maybe I am wrong here:) Not sure, but this could help: https://webpack.js.org/guides/production/
Hi Igor, It works great. Thank you for this post.
I was wondering how can I use it both for Woocommerce based site with a blog too, as for they are running on different REST API url.
Thanks
Hi,
This a very good article for me i have a query how can i enable geolocation Api in my React SearchBar with Wp Rest Api.Please Guide me.
Regards
Hi Robin, you can use the HTML5 Geolocation API and send such information to the search. But you would have to create a custom search route for that so you can provide content based on the geolocation.
Great post! But just curious – how can I make it redirect users to the original WordPress search page if they push “Enter”? As it works right now, it searches via the REST API perfectly, but if someone pushes “Enter” it redirects to the homepage with the URL “http://website.com/?” – just a “?” at the end. But I want it to be “?s=s%” to search the query in the normal way on “Enter.”